/**
 * MonitorInstances.java
 * ************************** 
 * @date May 26, 2011
 * @author Michele Tamburini
 * 
 * **************************
 */
package infrastructureAPI.algorithms.monitorTools;

import gossipServices.aggregation.AggregationService;
import gossipServices.basic.nodeDescriptors.ConcreteNodeDescriptor;
import gossipServices.basic.nodeDescriptors.NodeDescriptor;
import infrastructureAPI.Requester;
import infrastructureAPI.Service;
import infrastructureAPI.APIMessages.DispatcherRequestMessage;
import infrastructureAPI.APIMessages.RequestMessage;
import infrastructureAPI.algorithms.APIFunction;
import infrastructureAPI.algorithms.GeneralAPIFunctionAlgorithm;
import infrastructureAPI.backendGate.APIScript;

import java.net.InetAddress;
import java.util.List;
import java.util.Vector;

/**
 * Description: 
 * The MonitorInstances class implements the algorithm to monitor 
 * the number of nodes in the entire P2PCloudSystem.
 * 
 *
 */
public class MonitorInstances extends GeneralAPIFunctionAlgorithm 
		implements APIFunction, APIScript {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	protected long DEFAULT_INTERVAL_TIMER = 5000; //ms
	
	protected MonitorInstancesThread monitorThread;
	
	protected MonitorInstances(){}
	
	/**
	 * 
	 */
	public MonitorInstances(Requester requester) {
		super(requester);
	}

	@Override
	public RequestMessage createRequestMessage(InetAddress targetAddress,
			String targetNodeName) {
		NodeDescriptor sender = 
			new ConcreteNodeDescriptor(targetNodeName, targetAddress, null);
		return new DispatcherRequestMessage(sender, sender, this, requester);
	}

//	@Override
//	public boolean executeAlgorithm(List<Service> services) {
//		System.out.println("STARTING ALGORITHM: "+this.getClass().getSimpleName());
//		AggregationService agg = (AggregationService) services.get(0);
//		monitorThread = new MonitorInstancesThread(DEFAULT_INTERVAL_TIMER, agg);
//		monitorThread.startMonitor();
//		return true;
//	}

	@Override
	public Service extractSuppliedService() {
		return monitorThread;
	}

	@Override
	public boolean requireSystemRegistration() {
		return true;
	}

	@Override
	public List<Class<?>> requiredServices() {
		Vector<Class<?>> requiredServicesList = new Vector<Class<?>>();
		requiredServicesList.add(AggregationService.class);
		return requiredServicesList;
	}

	@Override
	public int mandatoryParametersNumber() {
		return 0;
	}

	@Override
	public String showUsage() {
		
		return "USAGE:\nmonitor-instances";
	}

	@Override
	public Service extractServiceToDeRegister() {
		return null;
	}

	@Override
	public boolean requireSystemDeRegistration() {
		return false;
	}

	@Override
	public boolean requireReply() {
		return true;
	}

	@Override
	public void run() {
		System.out.println(Thread.currentThread()+" is executing the "+
				this.getClass().getSimpleName()+" class");
//		System.out.println("STARTING ALGORITHM: "+this.getClass().getSimpleName());
		AggregationService agg = (AggregationService) services.get(0);
		monitorThread = new MonitorInstancesThread(DEFAULT_INTERVAL_TIMER, agg);
		monitorThread.startMonitor();
		returnValue = true;
	}

}
